package miage.rest.resource.candidature;

import com.thoughtworks.xstream.XStream;
import java.sql.SQLException;
import miage.rest.db.Database;
import miage.rest.model.Candidature;
import miage.rest.model.Candidat;
import miage.rest.model.Statut;
import miage.rest.resource.ResourceError;
import miage.rest.routing.UriTemplateFinder;
import miage.rest.security.Roles;
import miage.rest.validation.LongRangeValidator;
import miage.rest.xml.XstreamRepresentation;
import miage.rest.xml.xstream.converter.HrefConverter;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;

/**
 * Resource Candidature
 * @author Lou
 */
public class CandidatureResource extends ServerResource {

	private final Database database;
	private UriTemplateFinder uriTemplateFinder;
	private Candidature candidature;

	public CandidatureResource(Database database,
							   UriTemplateFinder uriTemplateFinder) {
		super();

		this.database = database;
		this.uriTemplateFinder = uriTemplateFinder;
	}

	/** Initialisation de la ressource a partir de la chaine d'url */
	@Override
	protected void doInit() throws ResourceException {

		final String sqlCandidature = "SELECT * FROM candidature WHERE id_candidature = ?";
		
		Long idCandidature;
		String idCandidatureAttribute = getRequest().getAttributes().get("idCandidature").toString();

		//Validation de l'id de la candidature
		LongRangeValidator longRangeValidator = new LongRangeValidator(1l, null);

		//Validation de l'id de la session
		if (longRangeValidator.isValid(idCandidatureAttribute)) {
			idCandidature = Long.parseLong(idCandidatureAttribute);
		} else {
			getResponse().setEntity(ResourceError.getNewRepresentation("invalidCandidatureId"));
			throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
		}

		//Validation du role
		if (!isInRole(Roles.ADMIN.getName())) {
			throw new ResourceException(Status.CLIENT_ERROR_UNAUTHORIZED);
		}
		
		//Recuperation de la candidature
		try {
			candidature = database.fetchRow(sqlCandidature, Candidature.class,
											idCandidature);
			if (candidature == null) {
				setExisting(false);
			}
		} catch (SQLException e) {
			throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
		}
	}

	/** Représentation XML en réponse à une requête GET.
	 * Jeu de caractères UTF-8
	 */
	@Get
	public Representation doGet() throws SQLException {
		Representation response;
		String sqlStatut = "SELECT * FROM statut WHERE id_statut = ?";

		//attribution du candidat:
		candidature.setCandidat(new Candidat(candidature.getIdCandidat()));

		// Récupération du statut pour la candidature en faisant appel à la base de données
		Statut statut = database.fetchRow(sqlStatut, Statut.class,
										  candidature.getIdStatut());
		candidature.setStatut(statut);

		//Création d'une représentation XStream de la candidature
		response = new XstreamRepresentation<Candidature>(candidature);
		XStream xstream = ((XstreamRepresentation) response).getXstream();

		//Ajout de l'intégration des liens href  pour la classe Candidat
		//par l'intermédiaire de la classe HrefConverter
		xstream.registerConverter(new HrefConverter(
				Candidat.class,
				xstream.getConverterLookup(),
				uriTemplateFinder.find(CandidatResource.class)));

		return response;
	}

	@Delete
	public void doDelete() throws Exception {
		String sqlUpdateCandidature = "UPDATE candidature SET id_statut = 4 WHERE id_candidature = ?";
		database.delete(sqlUpdateCandidature, candidature.getIdCandidature());
		setStatus(Status.SUCCESS_OK);
	}
}
